package com.gitee.mocoffee.log.spring;

import java.io.IOException;
import java.util.Arrays;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.MDC;

import com.gitee.mocoffee.misc.IdGenKit;

import jodd.util.StringUtil;

public class LogTraceFilter implements Filter {
    private static final String WEB_KEY_TRACEID = "__trace_id";
    private static final String LOG_TRACEID = "TRACEID";

    private String getTraceValue(HttpServletRequest request) {
        /*
         * 对controller方法标记trace
         * 获取优先级是:1.请求参数,2.请求头,3.cookie
         */
        String traceValue = null;
        traceValue = request.getParameter(WEB_KEY_TRACEID);
        if (StringUtil.isBlank(traceValue)) {
            traceValue = request.getHeader(WEB_KEY_TRACEID);
        }
        if (StringUtil.isBlank(traceValue)) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length > 0) {
                traceValue = Arrays.stream(request.getCookies())
                        .filter(c -> WEB_KEY_TRACEID.equals(c.getName()))
                        .map(c -> c.getValue())
                        .findAny()
                        .orElse(null);
            }
        }
        if (StringUtil.isBlank(traceValue)) {
            traceValue = IdGenKit.generate();
        }

        return traceValue;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        try {
            MDC.put(LOG_TRACEID, getTraceValue((HttpServletRequest) servletRequest));
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            MDC.remove(LOG_TRACEID);
        }
    }

    @Override
    public void destroy() {
    }
}
